package com.skynet.supervision.aop.validate;

import com.skynet.supervision.utils.Strings;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Objects;

@Slf4j
public class TsValidator implements ConstraintValidator<Ts, Long> {

    private Ts anno;

    @Override
    public void initialize(Ts constraintAnnotation) {
        anno = constraintAnnotation;
        val unit = anno.unit();
        if (unit != ChronoUnit.SECONDS && unit != ChronoUnit.MILLIS) {
            throw new RuntimeException(Strings.sprintf("时间戳单位:{}非法,只能是SECONDS/MILLIS", unit.toString()));
        }
    }

    @Override
    public boolean isValid(Long value, ConstraintValidatorContext context) {
        Objects.requireNonNull(anno);
        if (anno.required() && value == null) {
            return false;
        }
        if (value != null) {
            val unit = anno.unit();
            try {
                Instant instant = null;
                switch (unit) {
                    case SECONDS:
                        instant = Instant.ofEpochSecond(value);
                        break;
                    case MILLIS:
                        instant = Instant.ofEpochMilli(value);
                        break;
                    default:
                        break;
                }
                ;
                if (instant == null) {
                    return false;
                }
                /* 以下是非必要性检查,都是无意义的操作
                if (instant.isAfter(Instant.MAX)) {
                    context.disableDefaultConstraintViolation();
                    context.buildConstraintViolationWithTemplate(
                            Strings.sprintf("值:{},超过时间戳最大值", value))
                            .addConstraintViolation();
                    return false;
                }
                if (instant.isBefore(Instant.EPOCH)) {
                    context.disableDefaultConstraintViolation();
                    context.buildConstraintViolationWithTemplate(
                            Strings.sprintf("值:{},低于时间戳最小值", value))
                            .addConstraintViolation();
                    return false;
                } */
            } catch (Exception e) {
                log.error("单位:{},尝试解析时间:{},出现异常", unit.toString(), value);
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate(
                                Strings.sprintf("值:{},并不是{}单位的有效值", value, unit.toString()))
                        .addConstraintViolation();
                return false;
            }
        }
        return true;
    }
}
